﻿Imports Models.Security

Public Class Security
    Inherits BaseService

    Sub New(request As System.Net.Http.HttpRequestMessage)
        Me.loadToken(request)
    End Sub




    ''' <summary>
    ''' Login into MapGeoData app
    ''' </summary>
    ''' <param name="user"></param>
    ''' <param name="password"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function Login(user As String, password As String, Optional companyId As Integer = -1) As LoginResultVO

        Dim oResult As New LoginResultVO

        Try

            'password = CRIPT password
            Using oDB As New Data.BaseModel.BaseModelContainer("name=BaseModelContainer")



                Dim oDataEntity As Data.BaseModel.User = (From l In oDB.Users Where l.Login = user And l.Password = password Select l).FirstOrDefault()

                If oDataEntity IsNot Nothing Then

                    If oDataEntity.Active = False Then
                        oResult.result = LoginResultType.inactive
                    Else

                        If oDataEntity.Login = "super" Then
                            ensureUsersForSuper(oDB)
                            oDB.Refresh(Objects.RefreshMode.StoreWins, oDataEntity)
                        End If



                        If oDataEntity.UserCompanies.Count > 1 AndAlso companyId = -1 Then
                            oResult.result = LoginResultType.canbeselectcompany
                        Else

                            Dim userEntity As Data.BaseModel.UserCompany

                            ' get the company for companyId
                            Dim index As Integer = 0
                            If oDataEntity.UserCompanies.Count > 1 AndAlso companyId > 0 Then
                                For index = 0 To oDataEntity.UserCompanies.Count - 1
                                    If oDataEntity.UserCompanies(index).CompanyId = companyId Then
                                        Exit For
                                    End If
                                Next
                            End If
                            userEntity = oDataEntity.UserCompanies(index)

                            Dim oEntity As New ClientSessionVO()
                            oEntity.token = System.Guid.NewGuid.ToString()
                            oEntity.loginId = oDataEntity.UserId
                            oEntity.userId = userEntity.UserCompanyId
                            oEntity.userLogin = oDataEntity.Login
                            oEntity.userName = oDataEntity.FullName
                            oEntity.companyId = userEntity.CompanyId
                            oEntity.companyName = userEntity.Company.Name

                            oEntity.process = New Generic.List(Of String)
                            For Each oProcess As Data.BaseModel.Process In userEntity.Rol.Processes
                                oEntity.process.Add(oProcess.Code)
                            Next

                            SessionEngine.getInstance().createSession(oEntity)

                            oResult.result = LoginResultType.ok
                            oResult.session = oEntity

                            '' Try autoload model
                            'Dim autoload As String = (From p In userEntity.UserPreferences Where p.Preference.Code = "autoload_model" Select p.Value).FirstOrDefault()
                            'If Not String.IsNullOrEmpty(autoload) Then
                            '    Dim modelService As New Services.ModelManager()
                            '    modelService.token = oEntity.token
                            '    oEntity.modelInfo = modelService.OpenModel(autoload)
                            '    If Not String.IsNullOrEmpty(oEntity.modelInfo.newToken) Then
                            '        oEntity.token = oEntity.modelInfo.newToken
                            '    End If

                            'End If

                        End If
                    End If
                End If

            End Using

        Catch ex As Exception
            MainLib.Helpers.ExceptionWrapper(ex)
        End Try

        Return oResult

    End Function



    ''' <summary>
    ''' Get Companies from user
    ''' </summary>
    ''' <param name="user"></param>
    ''' <param name="password"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetUserCompanies(user As String, password As String) As Generic.List(Of Models.Users.CompanyVO)

        Dim oResult As New Generic.List(Of Models.Users.CompanyVO)

        Try

            'password = CRIPT password
            Using oDB As New Data.BaseModel.BaseModelContainer("name=BaseModelContainer")

                Dim oDataEntity As Data.BaseModel.User = (From l In oDB.Users Where l.Login = user And l.Password = password Select l).FirstOrDefault()

                If oDataEntity IsNot Nothing Then

                    If oDataEntity.Active Then
                        For Each dbUser As Data.BaseModel.UserCompany In oDataEntity.UserCompanies
                            oResult.Add(New Models.Users.CompanyVO(dbUser.Company))
                        Next
                    End If
                End If

            End Using

        Catch ex As Exception
            MainLib.Helpers.ExceptionWrapper(ex)
        End Try

        Return oResult

    End Function




    ''' <summary>
    ''' Logout and close sesion
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function Logout() As Boolean
        Try
            SessionEngine.getInstance().killSessionByToken(Me.token)
        Catch ex As Exception
            MainLib.Helpers.ExceptionWrapper(ex)
        End Try

        Return True

    End Function



    ''' <summary>
    ''' Purge sessions, kills sessions that have expired
    ''' </summary>
    ''' <remarks></remarks>
    Public Sub PurgeSessions()
        Try
            SessionEngine.getInstance.purgeSessions()
        Catch ex As Exception
            MainLib.Helpers.ExceptionWrapper(ex)
        End Try


    End Sub



    ''' <summary>
    ''' Return all my sessions
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetAllSessions(Optional ByVal userId As Integer = 0) As IEnumerable(Of ActiveSessionVO)
        Try

            If userId = 0 Then
                Me.checkAccess("GETALLSESSIONS")
            End If

            Dim oList As New Generic.List(Of ActiveSessionVO)
            Dim oActive As ActiveSessionVO
            For Each item As ItemSession In SessionEngine.getInstance.sessions.Values

                If userId = 0 Or userId = item.userId Then

                    oActive = New ActiveSessionVO(item.clientSession)
                    oActive.openAgo = DateDiff(DateInterval.Minute, item.openDateTime, Now)
                    oActive.activeAgo = DateDiff(DateInterval.Minute, item.lastUpdate, Now)
                    oActive.timeoutIn = Math.Max(item.timeout - oActive.activeAgo, 0)
                    'oActive.currentModel = item.modelData.currentModelId
                    ''
                    ''
                    ''
                    oList.Add(oActive)


                End If
            Next

            Return oList

        Catch ex As Exception
            MainLib.Helpers.ExceptionWrapper(ex)
        End Try

    End Function

    ''' <summary>
    ''' Return all my sessions
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetMySessions() As IEnumerable(Of ActiveSessionVO)
        Try
            Dim res As New Generic.List(Of ActiveSessionVO)
            If SessionEngine.getInstance.existsSession(Me.token) Then
                res = GetAllSessions(SessionEngine.getInstance.getSessionByToken(Me.token).userId)
            End If

            Return res

        Catch ex As Exception
            MainLib.Helpers.ExceptionWrapper(ex)
        End Try
    End Function

    ''' <summary>
    ''' Add all users/company relations for Super
    ''' </summary>
    ''' <remarks></remarks>
    Private Sub ensureUsersForSuper(ByRef oDB As Data.BaseModel.BaseModelContainer)

        Dim hasSave As Boolean = False

        Dim oSuper As Data.BaseModel.User = (From l In oDB.Users Where l.Login = "super" Select l).FirstOrDefault()
        Dim oCompanies As Generic.List(Of Data.BaseModel.Company) = (From c In oDB.Companies Select c).ToList()

        For Each company In oCompanies
            Dim lFound As Boolean = False

            Dim usersOk As Generic.List(Of Data.BaseModel.UserCompany) = (From u In oSuper.UserCompanies Where u.CompanyId = company.CompanyId Select u).ToList()
            If usersOk IsNot Nothing AndAlso usersOk.Count > 0 Then
                lFound = True
            End If
            If Not lFound Then

                Dim user As New Data.BaseModel.UserCompany()
                user.Company = company
                user.Rol = (From r In oDB.Rols Where r.Code = "user" Select r).FirstOrDefault()

                oSuper.UserCompanies.Add(user)
                hasSave = True
            End If
        Next

        If hasSave Then
            oDB.SaveChanges()
        End If


    End Sub

    ''' <summary>
    ''' Return all process
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetAllProcess() As IEnumerable(Of ProcessVO)
        Try
            Dim oResult As New Generic.List(Of ProcessVO)
            Using oDB As New Data.BaseModel.BaseModelContainer("name=BaseModelContainer")
                Dim query As IQueryable(Of Data.BaseModel.Process) = From c In oDB.Processes Order By c.Code Select c
                Dim oList As Generic.List(Of Data.BaseModel.Process) = query.ToList()

                For Each entity As Data.BaseModel.Process In oList
                    oResult.Add(New ProcessVO(entity))
                Next
            End Using

            Return oResult

        Catch ex As Exception
            MainLib.Helpers.ExceptionWrapper(ex)
        End Try
    End Function

End Class